package com.fsnbigdata.service.impl;
import com.fsnbigdata.domain.*;
import com.fsnbigdata.domain.dto.NamingPair;
import com.fsnbigdata.repository.EnterpriseImageRepository;
import com.fsnbigdata.service.api.EnterpriseService;
import com.fsnbigdata.util.ObjectNull;
import com.querydsl.core.types.Predicate;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.roo.addon.layers.service.annotations.RooServiceImpl;
import com.fsnbigdata.repository.EnterpriseRepository;
import com.fsnbigdata.service.api.EnterpriseEcosystemService;
import com.fsnbigdata.service.api.EnterpriseImageService;
import com.fsnbigdata.service.api.EnterpriseProductService;
import com.fsnbigdata.service.api.EntrepreneurService;
import io.springlets.data.domain.GlobalSearch;

import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Root;

/**
 * = EnterpriseServiceImpl
 *
 * TODO Auto-generated class documentation
 *
 */
@RooServiceImpl(service = EnterpriseService.class)
@Service
@Transactional(readOnly = true)
public class EnterpriseServiceImpl implements EnterpriseService {

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private EnterpriseEcosystemService enterpriseEcosystemService;

    @Autowired
    private EnterpriseImageRepository enterpriseImageRepository;

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private EnterpriseProductService enterpriseProductService;

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private EnterpriseRepository enterpriseRepository;

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private EntrepreneurService entrepreneurService;

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private EnterpriseImageService enterpriseImageService;

    /**
     * TODO Auto-generated constructor documentation
     *
     * @param enterpriseRepository
     * @param enterpriseEcosystemService
     * @param enterpriseImageService
     * @param enterpriseProductService
     * @param entrepreneurService
     */
    @Autowired
    public EnterpriseServiceImpl(EnterpriseRepository enterpriseRepository, @Lazy EnterpriseEcosystemService enterpriseEcosystemService, @Lazy EnterpriseImageService enterpriseImageService, @Lazy EnterpriseProductService enterpriseProductService, @Lazy EntrepreneurService entrepreneurService) {
        setEnterpriseRepository(enterpriseRepository);
        setEnterpriseEcosystemService(enterpriseEcosystemService);
        setEnterpriseImageService(enterpriseImageService);
        setEnterpriseProductService(enterpriseProductService);
        setEntrepreneurService(entrepreneurService);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return EnterpriseRepository
     */
    public EnterpriseRepository getEnterpriseRepository() {
        return enterpriseRepository;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param enterpriseRepository
     */
    public void setEnterpriseRepository(EnterpriseRepository enterpriseRepository) {
        this.enterpriseRepository = enterpriseRepository;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return EnterpriseEcosystemService
     */
    public EnterpriseEcosystemService getEnterpriseEcosystemService() {
        return enterpriseEcosystemService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param enterpriseEcosystemService
     */
    public void setEnterpriseEcosystemService(EnterpriseEcosystemService enterpriseEcosystemService) {
        this.enterpriseEcosystemService = enterpriseEcosystemService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return EnterpriseImageService
     */
    public EnterpriseImageService getEnterpriseImageService() {
        return enterpriseImageService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param enterpriseImageService
     */
    public void setEnterpriseImageService(EnterpriseImageService enterpriseImageService) {
        this.enterpriseImageService = enterpriseImageService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return EnterpriseProductService
     */
    public EnterpriseProductService getEnterpriseProductService() {
        return enterpriseProductService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param enterpriseProductService
     */
    public void setEnterpriseProductService(EnterpriseProductService enterpriseProductService) {
        this.enterpriseProductService = enterpriseProductService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return EntrepreneurService
     */
    public EntrepreneurService getEntrepreneurService() {
        return entrepreneurService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param entrepreneurService
     */
    public void setEntrepreneurService(EntrepreneurService entrepreneurService) {
        this.entrepreneurService = entrepreneurService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param enterprise
     * @param ecosystemsToAdd
     * @return Enterprise
     */
    @Transactional
    public Enterprise addToEcosystems(Enterprise enterprise, Iterable<EnterpriseEcosystem> ecosystemsToAdd) {
        enterprise.addToEcosystems(ecosystemsToAdd);
        return getEnterpriseRepository().save(enterprise);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param enterprise
     * @param entrepreneursToAdd
     * @return Enterprise
     */
    @Transactional
    public Enterprise addToEntrepreneurs(Enterprise enterprise, Iterable<Entrepreneur> entrepreneursToAdd) {
        enterprise.addToEntrepreneurs(entrepreneursToAdd);
        return getEnterpriseRepository().save(enterprise);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param enterprise
     * @param imagesToAdd
     * @return Enterprise
     */
    @Transactional
    public Enterprise addToImages(Enterprise enterprise, Iterable<EnterpriseImage> imagesToAdd) {
        enterprise.addToImages(imagesToAdd);
        return getEnterpriseRepository().save(enterprise);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param enterprise
     * @param productsToAdd
     * @return Enterprise
     */
    @Transactional
    public Enterprise addToProducts(Enterprise enterprise, Iterable<EnterpriseProduct> productsToAdd) {
        enterprise.addToProducts(productsToAdd);
        return getEnterpriseRepository().save(enterprise);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param enterprise
     * @param ecosystemsToRemove
     * @return Enterprise
     */
    @Transactional
    public Enterprise removeFromEcosystems(Enterprise enterprise, Iterable<Long> ecosystemsToRemove) {
        List<EnterpriseEcosystem> ecosystems = getEnterpriseEcosystemService().findAll(ecosystemsToRemove);
        enterprise.removeFromEcosystems(ecosystems);
        return getEnterpriseRepository().save(enterprise);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param enterprise
     * @param entrepreneursToRemove
     * @return Enterprise
     */
    @Transactional
    public Enterprise removeFromEntrepreneurs(Enterprise enterprise, Iterable<Long> entrepreneursToRemove) {
        List<Entrepreneur> entrepreneurs = getEntrepreneurService().findAll(entrepreneursToRemove);
        enterprise.removeFromEntrepreneurs(entrepreneurs);
        return getEnterpriseRepository().save(enterprise);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param enterprise
     * @param imagesToRemove
     * @return Enterprise
     */
    @Transactional
    public Enterprise removeFromImages(Enterprise enterprise, Iterable<Long> imagesToRemove) {
        List<EnterpriseImage> images = getEnterpriseImageService().findAll(imagesToRemove);
        enterprise.removeFromImages(images);
        return getEnterpriseRepository().save(enterprise);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param enterprise
     * @param productsToRemove
     * @return Enterprise
     */
    @Transactional
    public Enterprise removeFromProducts(Enterprise enterprise, Iterable<Long> productsToRemove) {
        List<EnterpriseProduct> products = getEnterpriseProductService().findAll(productsToRemove);
        enterprise.removeFromProducts(products);
        return getEnterpriseRepository().save(enterprise);
    }

    @Override
    public List<NamingPair> findAllByInitial(String initial) {
        return getEnterpriseRepository().findAllByInitial(initial);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param enterprise
     */
    @Transactional
    public void delete(Enterprise enterprise) {
        // Clear bidirectional one-to-many parent relationship with EnterpriseEcosystem
        for (EnterpriseEcosystem item : enterprise.getEcosystems()) {
            item.setEnterprise(null);
        }
        // Clear bidirectional one-to-many parent relationship with Entrepreneur
        for (Entrepreneur item : enterprise.getEntrepreneurs()) {
            item.setEnterprise(null);
        }
        // Clear bidirectional one-to-many parent relationship with EnterpriseImage
        for (EnterpriseImage item : enterprise.getImages()) {
            item.setEnterprise(null);
        }
        // Clear bidirectional one-to-many parent relationship with EnterpriseProduct
        for (EnterpriseProduct item : enterprise.getProducts()) {
            item.setEnterprise(null);
        }
        getEnterpriseRepository().delete(enterprise);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param entities
     * @return List
     */
    @Transactional
    public List<Enterprise> save(Iterable<Enterprise> entities) {
        return getEnterpriseRepository().save(entities);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param ids
     */
    @Transactional
    public void delete(Iterable<Long> ids) {
        List<Enterprise> toDelete = getEnterpriseRepository().findAll(ids);
        getEnterpriseRepository().deleteInBatch(toDelete);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param entity
     * @return Enterprise
     */
    @Transactional
    public Enterprise save(Enterprise entity) {

        entity.getEntrepreneurs().forEach(it -> it.setEnterprise(entity));
        entity.getEcosystems().forEach(it -> it.setEnterprise(entity));
        entity.getProducts().forEach(it -> it.setEnterprise(entity));
        entity.getImages().forEach(it -> it.setEnterprise(entity));

        return getEnterpriseRepository().save(entity);
    }

    @Override
    public Integer deleteImages(Long id) {
        return enterpriseImageRepository.deleteAllByEnterpriseId( id ) ;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param id
     * @return Enterprise
     */
    public Enterprise findOne(Long id) {
        return getEnterpriseRepository().findOne(id);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param id
     * @return Enterprise
     */
    public Enterprise findOneForUpdate(Long id) {
        return getEnterpriseRepository().findOneDetached(id);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param ids
     * @return List
     */
    public List<Enterprise> findAll(Iterable<Long> ids) {
        return getEnterpriseRepository().findAll(ids);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return List
     */
    public List<Enterprise> findAll() {
        return getEnterpriseRepository().findAll();
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return Long
     */
    public long count() {
        return getEnterpriseRepository().count();
    }

    @Override
    public Page<Enterprise> search(Predicate predicate, Pageable pageable) {
        return getEnterpriseRepository().findAll(predicate, pageable);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param globalSearch
     * @param pageable
     * @return Page
     */
    public Page<Enterprise> findAll(GlobalSearch globalSearch, Pageable pageable) {
        return getEnterpriseRepository().findAll(globalSearch, pageable, null);
    }

    @Override
    public Page<Enterprise> findAll(GlobalSearch globalSearch, Pageable pageable, String creator) {
        return getEnterpriseRepository().findAll(globalSearch, pageable, creator);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param ids
     * @param globalSearch
     * @param pageable
     * @return Page
     */
    public Page<Enterprise> findAllByIdsIn(List<Long> ids, GlobalSearch globalSearch, Pageable pageable) {
        return getEnterpriseRepository().findAllByIdsIn(ids, globalSearch, pageable);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return Class
     */
    public Class<Enterprise> getEntityType() {
        return Enterprise.class;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return Class
     */
    public Class<Long> getIdType() {
        return Long.class;
    }
    
    /**
     * 通过类型查询所有数据
     * @return
     */
    public List<List<Enterprise>> findAllByType() {
        List<List<Enterprise>> list = new ArrayList<>();
        for (Integer i = 0; i < 4; i++) {
            List<Enterprise> enterprises = getEnterpriseRepository().findAllByType(i);
            if (enterprises != null && enterprises.size() > 4) {
                list.add(enterprises.subList(0, 4));
            } else {
                list.add(enterprises);
            }
        }
        return list;
    }

    @Override
    public List findByPageAndSize(String type,String legalPerson,String organizationCode,
                                              String name, String category,String enterPriseName,
                                              String productName,Pageable pageable) {

        class NewEnterprise{

            private String id;
            private String creator;
            private String name;
            private String url;
            private String email;
            private String address;
            private String type;


            public String getId() {
                return id;
            }

            public void setId(String id) {
                this.id = id;
            }

            public String getCreator() {
                return creator;
            }

            public void setCreator(String creator) {
                this.creator = creator;
            }

            public String getName() {
                return name;
            }

            public void setName(String name) {
                this.name = name;
            }

            public String getUrl() {
                return url;
            }

            public void setUrl(String url) {
                this.url = url;
            }

            public String getEmail() {
                return email;
            }

            public void setEmail(String email) {
                this.email = email;
            }

            public String getAddress() {
                return address;
            }

            public void setAddress(String address) {
                this.address = address;
            }

            public String getType() {
                return type;
            }

            public void setType(String type) {
                this.type = type;
            }


        }

        List<Long> ids = new ArrayList<>();
        //根据企业家获取企业Id
        if (enterPriseName!=null&&!"".equals(enterPriseName)){
            ids = entrepreneurService.getIdsByName(enterPriseName);
        }
        //根据产品Id获取企业Id
        List<Long> ids1 = new ArrayList<>();
        if (productName!=null&&!"".equals(productName)){
            ids1 = enterpriseProductService.getIdsByName(productName);
        }

        String sign = ids.size()>0?ids.get(0)+"":null;
        ids = ids.size()>0?ids:null;

        String sign1 = ids1.size()>0?ids1.get(0)+"":null;
        ids1 = ids1.size()>0?ids1:null;
        List list = new ArrayList();
        List<NewEnterprise> newEnterprises =new ArrayList<>();
        List<Object> enterpriseList = enterpriseRepository.findAllByIdsAndTypeAndName(type,legalPerson,organizationCode,category,name,sign,sign1,ids,ids1,pageable);

        for (Object object:enterpriseList){
            Object[] obj = (Object[]) object;
            NewEnterprise newEnterprise = new NewEnterprise();
            newEnterprise.setId(""+obj[0]);
            newEnterprise.setName(ObjectNull.takeOutNull(obj[1]));
            newEnterprise.setCreator(ObjectNull.takeOutNull(obj[2]));
            newEnterprise.setEmail(ObjectNull.takeOutNull(obj[3]));
            newEnterprise.setAddress(ObjectNull.takeOutNull(obj[4]));
            newEnterprise.setType(ObjectNull.takeOutNull(obj[5]));
            if (enterpriseImageService.getUrl(Long.parseLong(newEnterprise.getId())).size()>0){
                newEnterprise.setUrl(enterpriseImageService.getUrl(Long.parseLong(newEnterprise.getId())).get(0));
            }

            newEnterprises.add(newEnterprise);
        }
        list.add(enterpriseRepository.CountByKey(type,legalPerson,organizationCode,category,name,sign,sign1,ids,ids1));
        list.add(newEnterprises);

        return list;
    }

    @Override
    public String findByNameById(Long id) {
        return enterpriseRepository.findNameById(id);
    }
}
